New function to set a callback to test if a node in drag can be dropped
authorJohn Ellis <johne@bellatlantic.net>
Sat, 15 Aug 1998 07:30:01 +0000 (07:30 +0000)
committerjohne <johne@src.gnome.org>
Sat, 15 Aug 1998 07:30:01 +0000 (07:30 +0000)
Sat Aug 15 03:19:30 1998  John Ellis  <johne@bellatlantic.net>

        * gtk/gtkctree.[ch] (gtk_ctree_set_drag_compare_func): New function
        to set a callback to test if a node in drag can be dropped onto
        it's currrent location.
        * gtk/gtkctree.c (set_mouse_cursor),(check_cursor): New functions
        to change the pointer when a drag destination is not allowed.

gtk/gtkctree.c
gtk/gtkctree.h

index e69dfac88a07f9f249ba7e609c681ed3641cae2e..8a11c67f6f7dcda2762b10c4d97478ecb566c08c 100644 (file)
@@ -191,8 +191,9 @@ static void real_undo_selection         (GtkCList      *clist);
 static void select_row_recursive        (GtkCTree      *ctree, 
                                         GtkCTreeNode  *node, 
                                         gpointer       data);
-
-
+static void set_mouse_cursor           (GtkCTree       *ctree,
+                                        gboolean       enable);
+static void check_cursor               (GtkCTree       *ctree);
 
 
 enum
@@ -409,6 +410,7 @@ gtk_ctree_init (GtkCTree *ctree)
   ctree->in_drag        = FALSE;
   ctree->drag_rect      = FALSE;
   ctree->line_style     = GTK_CTREE_LINES_SOLID;
+  ctree->drag_compare   = NULL;
 }
 
 static void
@@ -741,6 +743,7 @@ gtk_ctree_button_motion (GtkWidget      *widget,
                GTK_CTREE_NODE (g_list_nth (clist->row_list, row));
              ctree->drag_row = row;
              draw_xor_line (ctree);
+             check_cursor(ctree);
            }
          else if (ctree->drag_target &&
                   !GTK_CTREE_ROW (ctree->drag_target)->is_leaf)
@@ -758,6 +761,7 @@ gtk_ctree_button_motion (GtkWidget      *widget,
                GTK_CTREE_NODE (g_list_nth (clist->row_list, row));
              ctree->drag_row = row;
              draw_xor_rect (ctree);
+             check_cursor(ctree);
            }
        }
     }
@@ -785,6 +789,8 @@ gtk_ctree_button_release (GtkWidget      *widget,
 
       ctree->in_drag = FALSE;
 
+      set_mouse_cursor(ctree, TRUE);
+
       if (ctree->use_icons && ctree->drag_icon)
        {
          gdk_window_destroy (ctree->drag_icon);
@@ -820,31 +826,46 @@ gtk_ctree_button_release (GtkWidget      *widget,
            {
              if (GTK_CTREE_ROW (ctree->drag_target)->sibling != 
                  ctree->drag_source)
-               gtk_signal_emit (GTK_OBJECT (ctree), 
-                                ctree_signals[TREE_MOVE],
-                                ctree->drag_source,
-                                GTK_CTREE_ROW (ctree->drag_target)->parent,
-                                GTK_CTREE_ROW (ctree->drag_target)->sibling);
+               if (!ctree->drag_compare ||
+                   ctree->drag_compare (ctree,
+                                        ctree->drag_source,
+                                        GTK_CTREE_ROW (ctree->drag_target)->parent,
+                                        GTK_CTREE_ROW (ctree->drag_target)->sibling))
+                 gtk_signal_emit (GTK_OBJECT (ctree), 
+                                  ctree_signals[TREE_MOVE],
+                                  ctree->drag_source,
+                                  GTK_CTREE_ROW (ctree->drag_target)->parent,
+                                  GTK_CTREE_ROW (ctree->drag_target)->sibling);
            }
          else if (ctree->insert_pos == GTK_CTREE_POS_BEFORE)
            {
              if (GTK_CTREE_ROW (ctree->drag_source)->sibling != 
                  ctree->drag_target)
-               gtk_signal_emit (GTK_OBJECT (ctree), 
-                                ctree_signals[TREE_MOVE],
-                                ctree->drag_source,
-                                GTK_CTREE_ROW (ctree->drag_target)->parent,
-                                ctree->drag_target);
+               if (!ctree->drag_compare ||
+                   ctree->drag_compare (ctree,
+                                        ctree->drag_source,
+                                        GTK_CTREE_ROW (ctree->drag_target)->parent,
+                                        ctree->drag_target))
+                 gtk_signal_emit (GTK_OBJECT (ctree), 
+                                  ctree_signals[TREE_MOVE],
+                                  ctree->drag_source,
+                                  GTK_CTREE_ROW (ctree->drag_target)->parent,
+                                  ctree->drag_target);
            }
          else if (!GTK_CTREE_ROW (ctree->drag_target)->is_leaf)
            {
              if (GTK_CTREE_ROW (ctree->drag_target)->children !=
                  ctree->drag_source)
-               gtk_signal_emit (GTK_OBJECT (ctree), 
-                                ctree_signals[TREE_MOVE],
-                                ctree->drag_source,
-                                ctree->drag_target,
-                                GTK_CTREE_ROW (ctree->drag_target)->children);
+               if (!ctree->drag_compare ||
+                   ctree->drag_compare (ctree,
+                                        ctree->drag_source,
+                                        ctree->drag_target,
+                                        GTK_CTREE_ROW (ctree->drag_target)->children))
+                 gtk_signal_emit (GTK_OBJECT (ctree), 
+                                  ctree_signals[TREE_MOVE],
+                                  ctree->drag_source,
+                                  ctree->drag_target,
+                                  GTK_CTREE_ROW (ctree->drag_target)->children);
            }
        }
       ctree->drag_source = NULL;
@@ -5305,3 +5326,71 @@ real_undo_selection (GtkCList *clist)
     gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
 
 }
+
+void
+gtk_ctree_set_drag_compare_func (GtkCTree *ctree, GtkCTreeCompareDragFunc cmp_func)
+{
+  g_return_if_fail (ctree != NULL);
+  g_return_if_fail (GTK_IS_CTREE (ctree));
+
+  ctree->drag_compare = cmp_func;
+}
+
+static void
+set_mouse_cursor(GtkCTree *ctree, gboolean enable)
+{
+  GdkCursor *cursor;
+
+  g_return_if_fail (ctree != NULL);
+  g_return_if_fail (GTK_IS_CTREE (ctree));
+
+  if (enable)
+    cursor = gdk_cursor_new (GDK_LEFT_PTR);
+  else
+    cursor = gdk_cursor_new (GDK_CIRCLE);
+
+  gdk_window_set_cursor (GTK_CLIST(ctree)->clist_window, cursor);
+  gdk_cursor_destroy (cursor);
+}
+
+static void
+check_cursor(GtkCTree *ctree)
+{
+  g_return_if_fail (ctree != NULL);
+  g_return_if_fail (GTK_IS_CTREE (ctree));
+
+
+  if (!GTK_CTREE_ROW (ctree->drag_source)->children ||
+      !gtk_ctree_is_ancestor (ctree, ctree->drag_source, ctree->drag_target))
+    {
+    if (ctree->insert_pos == GTK_CTREE_POS_AFTER)
+      {
+      if (GTK_CTREE_ROW (ctree->drag_target)->sibling != ctree->drag_source)
+        set_mouse_cursor( ctree, (!ctree->drag_compare ||
+                                  ctree->drag_compare (ctree,
+                                  ctree->drag_source,
+                                  GTK_CTREE_ROW (ctree->drag_target)->parent,
+                                  GTK_CTREE_ROW (ctree->drag_target)->sibling)));
+      }
+    else if (ctree->insert_pos == GTK_CTREE_POS_BEFORE)
+      {
+      if (GTK_CTREE_ROW (ctree->drag_source)->sibling != ctree->drag_target)
+        set_mouse_cursor( ctree, (!ctree->drag_compare ||
+                                  ctree->drag_compare (ctree,
+                                  ctree->drag_source,
+                                  GTK_CTREE_ROW (ctree->drag_target)->parent,
+                                  ctree->drag_target)));
+      }
+    else if (!GTK_CTREE_ROW (ctree->drag_target)->is_leaf)
+      {
+      if (GTK_CTREE_ROW (ctree->drag_target)->children != ctree->drag_source)
+        set_mouse_cursor( ctree, (!ctree->drag_compare ||
+                                  ctree->drag_compare (ctree,
+                                  ctree->drag_source,
+                                  ctree->drag_target,
+                                  GTK_CTREE_ROW (ctree->drag_target)->children)));
+      }
+    }
+  else
+    set_mouse_cursor(ctree, FALSE);
+}
index c9d9b5e1bd844f0320366d8b5025f5bcadb10949..7765c75e7f38c1b9c249e6217f497610646ce8bb 100644 (file)
@@ -87,6 +87,11 @@ typedef gboolean (*GtkCTreeGNodeFunc) (GtkCTree     *ctree,
                                       GtkCTreeNode *cnode,
                                        gpointer      data);
 
+typedef gboolean (*GtkCTreeCompareDragFunc) (GtkCTree     *ctree,
+                                             GtkCTreeNode *source_node,
+                                             GtkCTreeNode *new_parent,
+                                             GtkCTreeNode *new_sibling);
+
 struct _GtkCTree
 {
   GtkCList clist;
@@ -109,6 +114,8 @@ struct _GtkCTree
   guint in_drag     : 1;
   guint drag_rect   : 1;
   guint line_style  : 2;
+
+  GtkCTreeCompareDragFunc drag_compare;
 };
 
 struct _GtkCTreeClass
@@ -372,6 +379,8 @@ void       gtk_ctree_set_use_drag_icons     (GtkCTree     *ctree,
                                             gboolean      use_icons);
 void       gtk_ctree_set_line_style         (GtkCTree     *ctree, 
                                             GtkCTreeLineStyle line_style);
+void       gtk_ctree_set_drag_compare_func  (GtkCTree                  *ctree,
+                                            GtkCTreeCompareDragFunc    cmp_func);            
 
 /***********************************************************
  *             Tree sorting functions                      *